#include <csapp.h>

void echo(int connfd);

void signal_handler(int sig) {
    while(waitpid(-1, 0, WNOHANG) > 0)
        ;
    return;
}

void command(void);

int main(int argc, char * argv[]) {
    int listenfd, connfd;
    socklen_t clientlen;
    sockaddr_storage clientaddr;
    fd_set read_set, ready_set;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <port>\n", argv[1]);
        return -1;
    }

    Signal(SIGCHLD, signal_handler);
    listenfd = Open_listenfd(atoi(argv[1]));

    FD_ZERO(&read_set);
    FD_SET(STDIN_FILENO, &read_set);
    FD_SET(listenfd, &read_set);

    while(1) {
        ready_set = read_set;
        Select(listenfd + 1, &read_set, NULL, NULL, NULL);
        if(FD_ISSET(STDIN_FILENO, &ready_set)) {
            command();
        }
        if(FD_ISSET(listenfd, &ready_set)) {
            clientlen = sizeof clientaddr;
            connfd = Accept(listenfd, (SA*)&clientaddr, &clientlen);
            echo(connfd);
            Close(connfd);
        }
        /*if (Fork() == 0) {
            // child
            Close(listenfd);
            echo(connfd);
            Close(connfd);
            exit(0);
        }
        Close(connfd);*/
    }
    return 0;
}

void echo(int connfd) {
    std::size_t n;
    char buf[MAXLINE];
    rio_t rio;

    Rio_readinitb(&rio, connfd);

    while ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) {
        printf("server received %d bytes\n", n);
        Rio_writen(connfd, buf, n);
    }
}

void command() {
    char buf[MAXLINE];
    if (!Fgets(buf, MAXLINE, stdin)) {
        exit(0);
    }
    printf("%s\n", buf);
}